<template>
    <!-- 响应式栅格列，点击卡片触发 handleClick -->
    <el-col :span="span" class="clickable-col">
        <div class="box" :class="{ bounce: isBouncing }" @click="handleClick">
            <div class="content">
                <!-- 图标区域 -->
                <div class="icon-container">
                    <el-icon :size="30" class="icon">
                        <component :is="icon" />
                    </el-icon>
                </div>
                <!-- 数字动画区域 -->
                <div class="data-container">
                    <el-statistic 
                        :title="title" 
                        :value="currentValue" 
                        :value-style="isTypeStyle"
                        :class="{ bounce: isNumberBouncing }"
                    />
                </div>
            </div>
        </div>
    </el-col>
</template>

<script setup>
// 引入 vue 相关方法
import { ref, onMounted, onUnmounted, watch } from 'vue'
// 引入防抖工具
import { debounce } from '@/tools/debounce.js'
// 引入 Element Plus 组件
import { ElCol, ElIcon, ElStatistic } from 'element-plus'

// props 定义
const props = defineProps({
    title: String,         // 卡片标题
    icon: Object,          // 图标组件
    startVal: Number,      // 动画起始值
    endVal: Number,        // 动画结束值
    duration: {
        type: Number,
        default: 1500      // 动画持续时间（毫秒）
    },
    span: {
        type: Number,
        default: 6         // el-col 跨度
    },
    getUrl: String,        // 传递给父组件的 url
    getUnit: String        // 传递给父组件的单位
})

// 当前显示的数字
const currentValue = ref(props.startVal)
let interval = null
const isTypeStyle = ref({ fontSize: '24px' }) // 默认大屏幕字体样式
const windowWidth = ref(window.innerWidth)
// 正确声明所有自定义事件
const emit = defineEmits(['giveUrl', 'click'])

// 跳动效果状态
const isBouncing = ref(false)
const isNumberBouncing = ref(false)

// 监听endVal变化，变化时触发跳动
watch(() => props.endVal, (newVal, oldVal) => {
    if (newVal !== oldVal && oldVal !== undefined) {
        isBouncing.value = true
        isNumberBouncing.value = true
        setTimeout(() => {
            isBouncing.value = false
            isNumberBouncing.value = false
        }, 600)
    }
    startTransition()
})

// 监听currentValue变化，数字跳动
watch(currentValue, (newVal, oldVal) => {
    if (newVal !== oldVal && oldVal !== undefined) {
        isNumberBouncing.value = true
        setTimeout(() => {
            isNumberBouncing.value = false
        }, 600)
    }
})

// 数字动画
const startTransition = () => {
    let start = props.startVal
    const end = props.endVal
    const step = (end - start) / (props.duration / 16)

    interval = setInterval(() => {
        if (start >= end) {
            clearInterval(interval)
            currentValue.value = end
        } else {
            start += step
            currentValue.value = Math.round(start)
        }
    }, 16)
}

// 组件挂载时初始化动画和监听窗口变化
onMounted(() => {
    window.addEventListener('resize', debounce(() => windowWidth.value = window.innerWidth, 200))
    startTransition()
})

// 组件卸载时清理定时器
onUnmounted(() => {
    if (interval) {
        clearInterval(interval)
    }
})

// 点击卡片时触发事件，向父组件传递 url 和单位
const handleClick = () => {
    emit('giveUrl', props.getUrl, props.getUnit)
    emit('click') // 新增：点击时触发 click 事件
}
</script>

<style scoped>
/* 响应式栅格列样式 */
.el-col {
    padding: 10px;
}

/* 卡片外层样式 */
.box {
    border: 1px solid #dcdfe6;
    border-radius: 4px;
    background-color: #fff;
    text-align: center;
    cursor: pointer;
    padding: 10px;
    background-color: var(--el-bg-color-page);
}

/* 鼠标悬浮卡片高亮 */
.box:hover {
    background-color: #f0f9eb;
    transform: translateY(-2px);
    transition: all 0.3s ease;
}

/* 卡片跳动效果 */
.box.bounce {
    animation: bounce 0.6s ease-in-out;
}

@keyframes bounce {
    0%, 20%, 50%, 80%, 100% {
        transform: translateY(0);
    }
    40% {
        transform: translateY(-10px);
    }
    60% {
        transform: translateY(-5px);
    }
}

/* 内容区域布局 */
.content {
    display: flex;
    align-items: center;
    justify-content: center;
}

/* 图标区域样式 */
.icon-container {
    margin-right: 10px;
}

/* 数字区域样式 */
.data-container {
    flex: 1;
}

/* 数字跳动效果 */
.data-container .el-statistic__content {
    transition: all 0.3s ease;
}

.data-container .el-statistic__content.bounce {
    animation: numberBounce 0.6s ease-in-out;
}

@keyframes numberBounce {
    0%, 20%, 50%, 80%, 100% {
        transform: scale(1);
    }
    40% {
        transform: scale(1.2);
    }
    60% {
        transform: scale(1.1);
    }
}

/* 移动端适配 */
@media (max-width: 768px) {
    .el-col {
        padding: 5px;
    }

    .box {
        padding: 5px;
    }

    .content {
        flex-direction: column;
        align-items: center;
    }

    .icon-container {
        margin-bottom: 10px;
        margin-right: 0;
    }

    .data-container {
        text-align: center;
    }
}
</style>